package qq2564874169.tuaotuao.fx.utils;

import qq2564874169.tuaotuao.fx.Dynamic;
import qq2564874169.tuaotuao.fx.FxStream;
import qq2564874169.tuaotuao.fx.json.Json;
import qq2564874169.tuaotuao.fx.json.jackson.JacksonImpl;

import java.lang.reflect.Array;
import java.util.List;
import java.util.Map;

public class JsonUtil {
    private static Json jsonImpl = new JacksonImpl();

    public static String toJson(Object object) {
        if (object instanceof Dynamic) {
            object = ((Dynamic) object).toMap();
        }
        return jsonImpl.toJson(object);
    }

    public static <T> T toObject(String json, Class<T> clazz) {
        if (clazz == Dynamic.class) {
            Map<?, ?> data = toObject(json, Map.class);
            return (T) new Dynamic(data);
        }
        return jsonImpl.toObject(json, clazz);
    }

    public static <T> List<T> toList(String json, Class<T> clazz) {
        if (clazz == Dynamic.class) {
            List<Map> list = toList(json, Map.class);
            return (List<T>) Dynamic.asList(list);
        }
        return jsonImpl.toList(json, clazz);
    }

    public static <T> T[] toArray(String json, Class<T> clazz) {
        if (clazz == Dynamic.class) {
            List<Map> list = toList(json, Map.class);
            T[] arr = (T[]) Array.newInstance(clazz, list.size());
            for (int i = 0; i < arr.length; i++) {
                arr[i] = (T) new Dynamic(list.get(i));
            }
            return arr;
        }
        var rs = jsonImpl.toList(json, clazz);
        return FxStream.create(rs).toArray(clazz);
    }

    public static <T> T toObject(String json, String path, Class<T> clazz) {
        if (clazz == Dynamic.class) {
            Map<?, ?> data = toObject(json, path, Map.class);
            return (T) new Dynamic(data);
        }
        return jsonImpl.toObject(json, path, clazz);
    }

    public static <T> List<T> toList(String json, String path, Class<T> clazz) {
        if (clazz == Dynamic.class) {
            List<Map> list = toList(json, path, Map.class);
            return (List<T>) Dynamic.asList(list);
        }
        return jsonImpl.toList(json, path, clazz);
    }

    public static <T> T[] toArray(String json, String path, Class<T> clazz) {
        if (clazz == Dynamic.class) {
            List<Map> list = toList(json, path, Map.class);
            T[] arr = (T[]) Array.newInstance(clazz, list.size());
            for (int i = 0; i < arr.length; i++) {
                arr[i] = (T) new Dynamic(list.get(i));
            }
            return arr;
        }
        var rs = jsonImpl.toList(json, path, clazz);
        return FxStream.create(rs).toArray(clazz);
    }

    public static String raw(String json, String path) {
        return jsonImpl.raw(json, path);
    }

    public static <T> T clone(Object pre, Class<T> clazz) {
        if (pre == null) {
            return null;
        }
        String json = pre instanceof String ? (String) pre : jsonImpl.toJson(pre);
        return jsonImpl.toObject(json, clazz);
    }
}
